using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;


namespace XTYAPI.PLC
{
    /// <summary>
    /// 接通延时
    /// 王栋 qq群1107658466
    /// 可以使用“接通延时”指令将 Q 参数的设置延时 PT 指定的一段时间。
    /// 当参数 IN 的逻辑运算结果 (RLO) 从“0”变为“1”（信号上升沿）时，启动该指令。指令启动时，预设的时间 PT 即开始计时。
    /// 超过持续时间 PT 时，参数 Q 的信号状态变为“1”。
    /// 只要启动输入仍为“1”，参数 Q 就保持置位。如果 IN 参数的信号状态从“1”变为“0”，则复位参数 Q。
    /// 当在参数 IN 上检测到一个新的信号上升沿时，将重新启动定时器功能。
    /// </summary>
    public class TON
    {
        #region 方法
        public TON()//构造函数 初始化定时器
        {
            long l = Stopwatch.Frequency;
            bool b = Stopwatch.IsHighResolution;
            sw = new Stopwatch();
            r_TRIG = new R_TRIG();//上升沿
            f_TRIG = new F_TRIG();//下降沿
        }
        public TON(uint pT) : this()//带参数构造函数
        {
            this.pT = pT;
        }
        #endregion
        #region 成员
        private Stopwatch sw;//stopwatch对象提供计时引擎
        private bool iN;//输入引脚
        private bool q;//输出引脚
        private uint pT;//定时
        R_TRIG r_TRIG;//上升沿
        F_TRIG f_TRIG;//下降沿     
        /// <summary>
        /// 时间到上升沿字段
        /// </summary>
        R_TRIG qP = new R_TRIG();
        /// <summary>
        /// 时间到下降沿
        /// </summary>
        F_TRIG fp=new F_TRIG();
        #endregion
        #region 属性
        public bool  IsRuning { get { return sw.IsRunning; } }
        /// <summary>
        /// 输入
        /// </summary>
        public bool IN
        {
            get { return iN; }
            set
            {
                r_TRIG.CLK = f_TRIG.CLK= value;//给检测沿脉冲对象引脚赋值
                if (r_TRIG.Q)//上升沿产生
                {
                    iN = true;
                   sw.Start();// 定时器计时开始           
                }
                if (f_TRIG.Q)//下降沿产生
                {
                    iN = false;
                    sw.Stop();//定时器停止工作
                    sw.Reset();//并且计时器当前值清0
                }                    
            }
        }
        /// <summary>
        /// 输出
        /// </summary>
        public bool Q
        {
            get
            {
                if (iN)//如果使能
                {
                    q = (uint)(sw.ElapsedMilliseconds) >= pT;//大于等于设定值输出
                    if (q)
                    {
                        sw.Stop();//输出后停止计时
                    }
                }
                else
                {
                    q = false;//没有使能 q点不输出
                }
                return q;
            }
        }
        /// <summary>
        /// 获取时间到上升沿
        /// </summary>
        public bool Qp { get { qP.CLK = Q; return qP.Q; } }

        /// <summary>
        /// 获取时间到下降沿
        /// </summary>
        public bool Qf { get { fp.CLK = Q; return fp.Q; } }
        /// <summary>
        /// 设定时间
        /// </summary>
        public uint PT { get { return pT; } set { pT = value; } }
        /// <summary>
        /// 当前运行时间
        /// </summary>
        public uint ET
        {
            get
            {
                if (q)
                {
                    return pT;
                }
                else
                {
                  return  (uint)(sw.ElapsedMilliseconds);
                }              
            }
        }
        #endregion
    }

}
